package tr.muyat.accelerometer.sender;

import java.nio.ByteBuffer;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

/**
 * 
 * @author fxulusoy
 */
public class AccelerometerSenderServiceActivity extends Activity {
	
    public static final String TAG = "AccSenderService";

    // Message types sent from the BluetoothChatService Handler
    public static final int MESSAGE_RECEIVED = 1;

    private Button startServiceButton;
    private Button stopServiceButton;
    private EditText xEditText;
    private EditText yEditText;
    private EditText zEditText;
    
    private SensorThread sensorThread;
    
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Obtain handles to UI objects
        xEditText = (EditText) findViewById(R.id.xEditText);
        yEditText = (EditText) findViewById(R.id.yEditText);
        zEditText = (EditText) findViewById(R.id.zEditText);
        startServiceButton = (Button) findViewById(R.id.startServiceButton);
        stopServiceButton = (Button) findViewById(R.id.stopServiceButton);
        startServiceButton.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				Log.d(TAG, "startServiceButton clicked");
				startService();
			}
		});
        
        stopServiceButton.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				Log.d(TAG, "stopServiceButton clicked");
				stopService();
			}
		});
        
    }
    
    private void startService() {
		sensorThread = new SensorThread();
		sensorThread.start();
    }
    
    private void stopService() {
		if(sensorThread != null) {
			sensorThread.cancel();
			sensorThread = null;
		}
    }
    
    
    /**
     * 
     * @author fxulusoy
     */
    class SensorThread extends Thread implements SensorEventListener {

    	private long lastUpdate;
    	private SenderClient senderClient;
    	private SensorManager sensorManager;

    	public SensorThread() {
    		sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    		lastUpdate = System.currentTimeMillis();
    		senderClient = new SenderClient();
    	}
    	
    	public void run() {
    		sensorManager.registerListener(this,
    				sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
    				SensorManager.SENSOR_DELAY_GAME);
    		senderClient.startConnection();
    	}
    	
    	public void cancel() {
    		sensorManager.unregisterListener(this);
    		senderClient.stopConnection();
    	}
    	
    	public void onSensorChanged(SensorEvent event) {
    		
//    		if(System.currentTimeMillis() < (lastUpdate + 1000)) {
//    			return;
//    		}

			if ((event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)) {
				float[] values = event.values;
				// Movement
				float x = values[0];
				float y = values[1];
				float z = values[2];

				float accelationSquareRoot = (x * x + y * y + z * z)
						/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
				if (accelationSquareRoot >= 1) {

    				lastUpdate = System.currentTimeMillis();
    				// Toast.makeText(this, "x=" + x + ", y=" + y + ", z=" + z, Toast.LENGTH_SHORT).show();
    				Log.w(TAG, "x: " + x + " y: " + y + " z: " + z);
    				
    				byte[] bufferArray = float2Byte(values); 
    				// Send the values to the UI Activity
    				mHandler.obtainMessage(MESSAGE_RECEIVED, -1, -1, bufferArray).sendToTarget();
    				
    				// float[] dummyArray = {(float) 12.34, (float) 67.32};
    				// Send the values to the server.
    				senderClient.send(bufferArray);
    			}
    		}

    	}

    	public void onAccuracyChanged(Sensor sensor, int accuracy) {
    		// TODO Auto-generated method stub
    	}
    	
    	/**
    	 * Writes floats to byte array
    	 * 
    	 * @param inData
    	 * @return
    	 */
		private final byte[] float2Byte(float[] inData) {
			int j = 0;
			int length = inData.length;
			byte[] outData = new byte[length * 4];
			for (int i = 0; i < length; i++) {
				int data = Float.floatToIntBits(inData[i]);
				outData[j++] = (byte) (data >>> 24);
				outData[j++] = (byte) (data >>> 16);
				outData[j++] = (byte) (data >>> 8);
				outData[j++] = (byte) (data >>> 0);
			}
			return outData;
		}
    }
    
    private final Handler mHandler = new Handler() {
    	
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_RECEIVED:
            	byte[] buffer = (byte[]) msg.obj;
            	Log.i(TAG, MESSAGE_RECEIVED + ": " + msg.arg1);
            	float[] floatValues = convertToFloat(buffer, buffer.length);
            	
				xEditText.setText(Float.toString(floatValues[0]));
				yEditText.setText(Float.toString(floatValues[1]));
				zEditText.setText(Float.toString(floatValues[2]));
				xEditText.refreshDrawableState();
				yEditText.refreshDrawableState();
				zEditText.refreshDrawableState();
            }
        }
        
    	private float[] convertToFloat(byte[] buffer, int length) {
    		
    		float[] accValues = new float[length / 4];
    		ByteBuffer buf = ByteBuffer.wrap(buffer, 0, length);
    		for (int i = 0; i < length / 4; i++) {
    			switch (i) {
    			case 0:
    				accValues[0] = buf.getFloat();
    				break;
    			case 1:
    				accValues[1] = buf.getFloat();
    				break;
    			case 2:
    				accValues[2] = buf.getFloat();
    				break;				
    			default:
    				System.out.println("Unknown ");
    				break;				
    			}
    		}
    	
    		return accValues;
    	}
        
    };
    
}

